package com.lincoln.system.app.api;

import com.lincoln.bean.ApiCode;
import com.lincoln.bean.ApiCodeException;
import com.lincoln.bean.BaseSecurityApi;
import com.lincoln.entity.role.DbRole;
import com.lincoln.entity.user.DbUser;
import com.lincoln.service.RoleService;
import com.lincoln.service.UserService;
import com.lincoln.system.app.model.UserVO;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/user")
@CrossOrigin
public class UserApi extends BaseSecurityApi {
    @Autowired
    UserService userService;
    @Autowired
    RoleService roleService;

    @GetMapping("/list")
    @PreAuthorize("hasAuthority('role_admin')")
    public ApiCode list(Integer pageNo, Integer pageSize, String userName, Long roleId) {
        if (pageNo == null) {
            pageNo = 0;
        }
        if (pageSize == null) {
            pageSize = 10;
        }
        PageRequest pageRequest = userService.buildPageRequest(pageNo, pageSize, Sort.Order.desc("createTime"));
        Map<String, Object> params = new HashMap<>();
        if (StringUtils.isNotEmpty(userName)) {
            params.put("username", userName);
        }
        if (roleId != null) {
            params.put("roleId", roleId);
        }
        Page<DbUser> page = userService.findPage(pageRequest, params);
        return ApiCode.build(UserVO.parsePageUserVO(page));
    }

    @GetMapping("/info")
    @PreAuthorize("hasAuthority('role_admin')")
    public ApiCode info() throws Exception {
        checkLogin();
        DbUser user = getUser();
        UserVO userVO = new UserVO(user);
        return ApiCode.build(userVO);
    }

    @GetMapping("/{id}")
    @PreAuthorize("hasAuthority('role_admin')")
    public ApiCode info(@PathVariable Long id) throws Exception {
        if (id == null) {
            throw new ApiCodeException(10001);
        }
        DbUser user = userService.findById(id);
        if (user == null) {
            throw new ApiCodeException(10006);
        }
        UserVO userVO = new UserVO(user);
        return ApiCode.build(userVO);
    }

    @PutMapping("/add")
    @PreAuthorize("hasAuthority('role_admin')")
    public ApiCode add(String userName, String password, Long roleId) throws Exception {
        if (StringUtils.isEmpty(userName)) {
            throw new ApiCodeException(20001);
        }
        if (StringUtils.isEmpty(password)) {
            throw new ApiCodeException(20002);
        }
        if (roleId == null) {
            throw new ApiCodeException(20003);
        }
        DbRole role = roleService.findById(roleId);
        if (roleId == null) {
            throw new ApiCodeException(20003);
        }
        DbUser user = userService.findByUserName(userName);
        if (user != null) {
            throw new ApiCodeException(20004);
        }
        user = new DbUser();
        user.setUserName(userName);
        user.setPassword(PasswordEncoderFactories.createDelegatingPasswordEncoder().encode(password));
        user.setAccountNonExpired(true);
        user.setCredentialsNonExpired(true);
        user.setAccountNonLocked(true);
        user.setEnabled(true);
        user.setRole(role);
        userService.save(user);
        return ApiCode.findCode(ApiCode.SUCCESS);
    }

    @PostMapping("/{id}")
    @PreAuthorize("hasAuthority('role_admin')")
    public ApiCode edit(@PathVariable Long id, String password, Long roleId) throws Exception {
        if (id == null) {
            throw new ApiCodeException(10001);
        }
        if (StringUtils.isEmpty(password) && roleId == null) {
            throw new ApiCodeException(10001);
        }
        DbUser user = userService.findById(id);
        if (user == null) {
            throw new ApiCodeException(10006);
        }
        if (StringUtils.isNotEmpty(password)) {
            user.setPassword(PasswordEncoderFactories.createDelegatingPasswordEncoder().encode(password));
        }
        if (roleId != null) {
            DbRole role = roleService.findById(roleId);
            if (role == null) {
                throw new ApiCodeException(10006);
            }
            user.setRole(role);
        }
        userService.save(user);
        return ApiCode.findCode(ApiCode.SUCCESS);
    }


}
